/*
 *  liquidity/filter.vala
 *
 *  Copyright (c) 2008 Patrick Walton <pcwalton@uchicago.edu>
 */

using GLib;
using Gee;
using Clutter;

namespace Liquidity {
    public abstract class Filter : Object, IAnimatable {
        protected abstract string# glsl_source {
            get {
                return null;
            }
        }

        protected abstract HashMap<string, weak Float> glsl_params {
            get {
                return null;
            }
        }

        private HashMap<string, weak Float> presentation_params;

        private ActorModel _actor_model = null;

        construct {
            presentation_params = new HashMap<string, weak Float>();
        }

        protected Shader generate_shader()
        {
            Shader shader = new Shader();
            shader.set_fragment_source(glsl_source, 0);

            try {
                stdout.printf("Binding\n");
                shader.bind();
            } catch (GLib.Error err) {
                stdout.printf("Unsupported shader\n");
            }

            return shader;
        }

        public void _set_actor_model(ActorModel am)
        {
            assert(am != null);
            _actor_model = am;

            _actor_model.actor.set_shader(generate_shader());

            Gee.Set<string> keys = glsl_params.get_keys();
            foreach (string k in keys) {
                float val = glsl_params.get(k).val;

                /* FIXME: this leaks memory! */
                Float *fp = new Float(val);
                presentation_params.set(k, fp);
                stdout.printf("setting %s to %g\n", k, val);
                _actor_model.actor.set_shader_param(k, val);
            }
        }

        public void _remove_from_actor_model()
        {
            if (_actor_model != null)
                _actor_model.actor.set_shader(null);

            _actor_model = null;
        }

        public void _set_presentation_param(string key, float val)
        {
            float *ppp = new float[1]; *ppp = val;
            presentation_params.set(key, ppp);
        }

        public Behaviour get_behavior_for_key_path(string key_path, Alpha
                alpha, Timeline timeline)
        {
            if (glsl_params.get(key_path) != null) {
                Float pf = presentation_params.get(key_path);
                Float gf = glsl_params.get(key_path);
                return new FilterBehavior(this, key_path, pf.val, gf.val);
            } else
                return null; 
        }
    }
}

